package fachade;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import modelo.Area;
import modelo.Caja;
import modelo.Carta;
import modelo.Comanda;
import modelo.Cuenta;
import modelo.Deposito;
import modelo.EstadisticaPermanencia;
import modelo.Insumo;
import modelo.ItemCarta;
import modelo.ItemComanda;
import modelo.ItemReceta;
import modelo.MedioPago;
import modelo.Mesa;
import modelo.Mozo;
import modelo.Plato;
import modelo.Receta;
import modelo.Restaurante;
import modelo.Rubro;
import modelo.Sector;
import modelo.Area;
import modelo.Caja;
import modelo.Carta;
import modelo.Comanda;
import modelo.Cuenta;
import modelo.Deposito;
import modelo.EstadisticaPermanencia;
import modelo.Insumo;
import modelo.ItemCarta;
import modelo.ItemComanda;
import modelo.ItemReceta;
import modelo.MedioPago;
import modelo.Mesa;
import modelo.Mozo;
import modelo.Plato;
import modelo.Receta;
import modelo.Restaurante;
import modelo.Rubro;
import modelo.Sector;
import modelo.Area;
import modelo.Caja;
import modelo.Carta;
import modelo.Comanda;
import modelo.Cuenta;
import modelo.Deposito;
import modelo.EstadisticaPermanencia;
import modelo.Insumo;
import modelo.ItemCarta;
import modelo.ItemComanda;
import modelo.ItemReceta;
import modelo.MedioPago;
import modelo.Mesa;
import modelo.Mozo;
import modelo.Plato;
import modelo.Receta;
import modelo.Restaurante;
import modelo.Rubro;
import modelo.Sector;
import modelo.Area;
import modelo.Caja;
import modelo.Carta;
import modelo.Comanda;
import modelo.Cuenta;
import modelo.Deposito;
import modelo.EstadisticaPermanencia;
import modelo.Insumo;
import modelo.ItemCarta;
import modelo.ItemComanda;
import modelo.ItemReceta;
import modelo.MedioPago;
import modelo.Mesa;
import modelo.Mozo;
import modelo.Plato;
import modelo.Receta;
import modelo.Restaurante;
import modelo.Rubro;
import modelo.Sector;
import modelo.Area;
import modelo.Caja;
import modelo.Carta;
import modelo.Comanda;
import modelo.Cuenta;
import modelo.Deposito;
import modelo.EstadisticaPermanencia;
import modelo.Insumo;
import modelo.ItemCarta;
import modelo.ItemComanda;
import modelo.ItemReceta;
import modelo.MedioPago;
import modelo.Mesa;
import modelo.Mozo;
import modelo.Plato;
import modelo.Receta;
import modelo.Restaurante;
import modelo.Rubro;
import modelo.Sector;
import beans.ItemComandaBean;

import modelo.Area;
import modelo.Caja;
import modelo.Carta;
import modelo.Comanda;
import modelo.Cuenta;
import modelo.Deposito;
import modelo.EstadisticaPermanencia;
import modelo.Insumo;
import modelo.ItemCarta;
import modelo.ItemComanda;
import modelo.ItemReceta;
import modelo.MedioPago;
import modelo.Mesa;
import modelo.Mozo;
import modelo.Plato;
import modelo.Receta;
import modelo.Restaurante;
import modelo.Rubro;
import modelo.Sector;
import entity.AreaBD;
import entity.CajaBD;
import entity.CartaBD;
import entity.ComandaBD;
import entity.CuentaBD;
import entity.DepositoBD;
import entity.EstadisticaPermanenciaBD;
import entity.FacturaBD;
import entity.InsumoBD;
import entity.ItemCartaBD;
import entity.ItemComandaBD;
import entity.ItemFacturaBD;
import entity.ItemRecetaBD;
import entity.MedioPagoBD;
import entity.MesaBD;
import entity.MozoBD;
import entity.PlatoBD;
import entity.RecetaBD;
import entity.RegistroAtencionBD;
import entity.RestauranteBD;
import entity.RubroBD;
import entity.SectorBD;

public class PrincipalFachade {

	private static PrincipalFachade iController;
	private MesasFachade mesasFachade;
	private MozosFachade mozosFachade;
	private RestauranteFachade restauranteFachade;

	public static PrincipalFachade getInstance() {
		if (iController == null)
			iController = new PrincipalFachade();
		return iController;
	}

	private PrincipalFachade() {
		this.mesasFachade = new MesasFachade();
		this.mozosFachade=new MozosFachade();
		this.restauranteFachade=new RestauranteFachade();
	}
	
	public List<Restaurante> getRestaurantes(){
		List<Restaurante> mozos = new LinkedList<Restaurante>();
		for (RestauranteBD restaurante: this.restauranteFachade.getRestaurantes()){
			mozos.add(this.convertResturanteBdToModelo(restaurante));
		}
		return mozos;
	}
	
	public List<MedioPago> getMediosPago(){
		List<MedioPago> mediosPago = new LinkedList<MedioPago>();
		for (MedioPagoBD restaurante: this.restauranteFachade.getMediosPago()){
			mediosPago.add(this.convertMedioPagoBdToModelo(restaurante));
		}
		return mediosPago;
	}
	
	public List<Mozo> getMozos(Integer restaurante){
		List<Mozo> mozos=new ArrayList<Mozo>();
		for(MozoBD mozoBd:this.mozosFachade.getMozos(restaurante)){			
			mozos.add(this.convertMozoBdToModelo(mozoBd));
		}
		return mozos;
	}
	
	public List<Mesa> getMesasDeMozo(Integer legajo) {
		List<Mesa> mesas = new ArrayList<Mesa>();
		MozoBD mozo= this.mozosFachade.getMozo(legajo);
		SectorBD sector= mozo.getSector();
		for (MesaBD mesa: this.mesasFachade.getMesasOfSector(sector.getIdSector().getIdRestaurante(),
				sector.getIdSector().getIdSector())) {
			MesaBD mesaBd = (MesaBD) mesa;
			mesas.add(this.convertMesaBdToModelo(mesaBd));
		}
		return mesas;
	}
	
	public List<Mesa> getMesasPorEstado(String estado) {
		List<Mesa> mesas = new ArrayList<Mesa>();
		for (Iterator<MesaBD> iterator = this.mesasFachade.getMesasByEstado(estado)
				.iterator(); iterator.hasNext();) {
			MesaBD mesa = (MesaBD) iterator.next();
			mesas.add(this.convertMesaBdToModelo(mesa));
		}
		return mesas;
	}
		
	private Restaurante convertResturanteBdToModelo(RestauranteBD restaurante) {
		Restaurante r = new Restaurante();
		r.setNombre(restaurante.getNombre());
		r.setDireccion(restaurante.getDireccion());
		
		r.setDeposito(this.convertDepositoBdToModelo(restaurante.getDeposito()));
		r.setCaja(this.convertCajaBdToModelo(restaurante.getCaja()));
		r.setCarta(this.convertCartaBdToModelo(restaurante.getCarta()));
		
		if (r.getAreas()!=null) {
			for (AreaBD area: restaurante.getAreas())
				r.getAreas().add(this.convertAreaBdToModelo(area));
		}
		
		if (r.getSectores()!=null){
			for (SectorBD sector: restaurante.getSectores())
				r.getSectores().add(this.convertSectorBdToModelo(sector));
		}
		
		if (r.getMozos()!=null){
			for (MozoBD mozo: restaurante.getMozos())
				r.getMozos().add(this.convertMozoBdToModelo(mozo));
		}	
		
		return r;
	}
	
	private Deposito convertDepositoBdToModelo(DepositoBD deposito) {
		Deposito d = new Deposito();
		d.setNombre(deposito.getNombre());
		return d;
	}
	
	private Caja convertCajaBdToModelo(CajaBD caja) {
		Caja c = new Caja();
		c.setUltCierre(caja.getUltCierre());
		return c;
	}
	
	private MedioPago convertMedioPagoBdToModelo(MedioPagoBD medioPago) {
		MedioPago mp = new MedioPago();
		mp.setCodigo(medioPago.getCodigo());
		mp.setDescripcion(medioPago.getDescripcion());
		mp.setCuenta(this.convertCuentaBdToModelo(medioPago.getCuenta()));
		return mp;
	}
	
	private Cuenta convertCuentaBdToModelo(CuentaBD cuenta) {
		Cuenta c = new Cuenta();
		c.setCuentaId(cuenta.getCuentaId());
		c.setDescripcion(cuenta.getDescripcion());
		return c;
	}
	
	private Carta convertCartaBdToModelo(CartaBD carta) {
		Carta c = new Carta();
		c.setFechaDesde(carta.getFechaDesde());
		c.setFechaHasta(carta.getFechaHasta());
		if (c.getItemsCarta()!=null){
			for (ItemCartaBD item: carta.getItemsCarta())
				c.getItemsCarta().add(this.convertItemCartaBdToModelo(item));
		}
		return c;
	}
	
	private ItemCarta convertItemCartaBdToModelo(ItemCartaBD itemCarta) {
		ItemCarta ic = new ItemCarta();
		ic.setPrecio(itemCarta.getPrecio());
		ic.setRubro(this.convertRubroBdToModelo(itemCarta.getRubro()));
		ic.setPlato(this.convertPlatoBdToModelo(itemCarta.getPlato()));
		return ic;
	}
	
	private Rubro convertRubroBdToModelo(RubroBD rubro) {
		Rubro r = new Rubro();
		r.setCodigo(rubro.getCodigo());
		r.setDescripcion(rubro.getDescripcion());
		return r;
	}
	
	private Mozo convertMozoBdToModelo(MozoBD mozo) {
		Mozo m = new Mozo();
		m.setLegajo(mozo.getLegajo());
		m.setNombre(mozo.getNombre());
		m.setPorcComision(mozo.getPorcComision());
		if(mozo.getSector() != null){
			m.setSector(this.convertSectorBdToModelo(mozo.getSector()));
		}
		return m;
	}
	
	private Sector convertSectorBdToModelo(SectorBD sector){
		Sector s=new Sector();
		s.setNombre(sector.getNombre());
		if (sector.getMesas()!=null) {
			for (MesaBD mesa: sector.getMesas())
				s.getMesas().add(this.convertMesaBdToModelo(mesa));
		}
		return s;
	}

	private Mesa convertMesaBdToModelo(MesaBD mesa) {
		Mesa m = new Mesa();
		m.setCantLugares(mesa.getCantLugares());
		for (Iterator<ComandaBD> iterator = mesa.getComandas().iterator(); iterator
				.hasNext();) {
			ComandaBD comanda = (ComandaBD) iterator.next();
			m.getComandas().add(this.convertComandaBdToModelo(comanda, m));

		}
//		for (Iterator<EstadisticaPermanenciaBD> iterator = mesa.getEstadisticas().iterator(); iterator
//				.hasNext();) {
//			EstadisticaPermanenciaBD estadistica = (EstadisticaPermanenciaBD) iterator
//					.next();
//			m.getEstadisticas().add(
//					this.convertEstadisticaPermanenciaBdToModelo(estadistica));
//
//		}
		m.setEstado(mesa.getEstado());
//		for (Iterator iterator = mesa.getMesas().iterator(); iterator.hasNext();) {
//			this.convertMesaBdTOModelo(m.getMesas());
//		}
		//m.setMozo(this.convertMozoBdTOModel(mesa.getMozo()));
		m.setNumero(mesa.getPk().getNumero());

		return m;
	}

	private EstadisticaPermanencia convertEstadisticaPermanenciaBdToModelo(
			EstadisticaPermanenciaBD estadistica) {
		EstadisticaPermanencia e = new EstadisticaPermanencia();
		return e;
	}

	private Comanda convertComandaBdToModelo(ComandaBD comanda, Mesa mesa) {
		Comanda c = new Comanda();
		c.setArea(this.convertAreaBdToModelo(comanda.getArea()));
		c.setEstado(comanda.getEstado());
		c.setFecha(comanda.getFecha());
		for (Iterator<ItemComandaBD> iterator = comanda.getItemsComanda().iterator(); iterator
				.hasNext();) {
			ItemComandaBD item = (ItemComandaBD) iterator.next();
			c.getItemsComanda().add(this.convertItemComandaBdToModelo(item));
		}
		c.setMesa(mesa);
		c.setNumero(comanda.getIdComanda());

		return c;
	}

	private ItemComanda convertItemComandaBdToModelo(ItemComandaBD item) {
		ItemComanda i = new ItemComanda();
		i.setCantidad(item.getCantidad());
		i.setEstado(item.getEstado());
		i.setFacturar(item.getFacturar());
		i.setPlato(this.convertPlatoBdToModelo(item.getPlato()));
		return i;
	}

	private Plato convertPlatoBdToModelo(PlatoBD plato) {
		Plato p = new Plato();
		p.setArea(this.convertAreaBdToModelo(plato.getArea()));
		p.setPorcComision(plato.getPorcComision());
		p.setDescripcion(plato.getDescripcion());
		p.setReceta(this.convertRecetaBdToModelo(plato.getReceta()));
		return p;
	}

	private Receta convertRecetaBdToModelo(RecetaBD receta) {
		Receta r = new Receta();
		r.setHorasElaboracion(receta.getHorasElaboracion());
		for (Iterator<ItemRecetaBD> iterator = receta.getIngredientes().iterator(); iterator
				.hasNext();) {
			ItemRecetaBD itemRecetaBD = (ItemRecetaBD) iterator.next();
			r.getIngredientes().add(this.convertItemRecetaBdToModelo(itemRecetaBD));
		}
		r.setInstrucciones(receta.getInstrucciones());
		return r;
	}

	private ItemReceta convertItemRecetaBdToModelo(ItemRecetaBD itemRecetaBD) {
		ItemReceta i = new ItemReceta();
		i.setCantidad(itemRecetaBD.getCantidad());
		i.setIngrediente(this.convertInsumoBdToModelo(itemRecetaBD
				.getIngrediente()));
		return i;
	}

	private Insumo convertInsumoBdToModelo(InsumoBD insumo) {
		Insumo i = new Insumo();
		for (Iterator iterator = insumo.getSustitutos().iterator(); iterator
				.hasNext();) {
			InsumoBD insumo2 = (InsumoBD) iterator.next();
			i.getSustitutos().add(this.convertInsumoBdToModelo(insumo2));
		}
		return i;
	}

	private Area convertAreaBdToModelo(AreaBD area) {
		Area a = new Area();
		a.setNombre(area.getNombre());
		a.setDeposito(this.convertDepositoBdToModelo(area.getIdDeposito()));
		return a;
	}

	public void liberarMesa(Integer restaurante, Integer mesa) {
		MesaBD m = this.getMesaRestaurante(restaurante, mesa);
		m.setEstado("libre");
		mesasFachade.liberarMesa(m);
	}
	
	public void registrarAperturaMesa(Integer legajo, Integer numeroMesa, Integer cantComensales) {
		MesaBD mesa = this.getMesaRestaurante(1, numeroMesa);
		MozoBD mozo=this.mozosFachade.getMozo(legajo);
		mesa.setEstado("ocupada");
		
		RegistroAtencionBD registro=new RegistroAtencionBD();
		registro.setMozo(mozo);
		registro.setCantComensales(cantComensales);
		
		Calendar c=Calendar.getInstance();
		registro.setFecha(c.getTime());
		registro.setHora(0);
		registro.setMinutos(0);
		
		mesasFachade.AbrirMesa(mesa,registro);
	}
	
	public void generarFactura(Integer mesa, Integer medioPago){
		MesaBD m = this.getMesaRestaurante(1, mesa);
		MedioPagoBD mp=this.restauranteFachade.getMedioPago(medioPago);
		MozoBD mozo=m.getMozo();
		
		m.setEstado("facturada");
		
		FacturaBD factura=new FacturaBD();
		factura.setMozo(mozo);
		factura.setMedioPago(mp);
		
		Calendar c=Calendar.getInstance();		
		factura.setFecha(c.getTime());
		
		
		
		for (ComandaBD comanda: m.getComandas()) {
			for (ItemComandaBD item: comanda.getItemsComanda()) {
				ItemFacturaBD itemFC=new ItemFacturaBD();
				
				itemFC.setPlato(item.getPlato());
				itemFC.setCantidad(item.getCantidad());
				itemFC.setPrecio(item.getPlato().getPrecio());				
				factura.getItems().add(itemFC);
			}
		}
		
		EstadisticaPermanenciaBD estadistica=new EstadisticaPermanenciaBD();
		estadistica.setFechaDesde(c.getTime());
		
		this.mesasFachade.administrarFacturacion(m, factura, estadistica);
	}

	public MesaBD getMesaRestaurante(Integer restaurante, Integer mesa) {
//		RestauranteBD restauranteBd = restauranteFachade.getRestaurante(restaurante);
//		if(restauranteBd.getSectores() != null){
//			for (Iterator iterator = restauranteBd.getSectores().iterator(); iterator.hasNext();) {
//				SectorBD sector = (SectorBD) iterator.next();
//				for (Iterator<MesaBD> iterator2 = sector.getMesas().iterator(); iterator2
//						.hasNext();) {
//					MesaBD mesaBd = (MesaBD) iterator2.next();
//					if(mesaBd.getPk().getNumero().equals(mesa))
//						return mesaBd;
//				}
//			}
//		}
		for (Iterator iterator = mesasFachade.getMesas().iterator(); iterator.hasNext();) {
			MesaBD m = (MesaBD) iterator.next();
			if(m.getPk().getNumero().equals(mesa))
				return m;
		}
		return null;
	}

	public MesaBD buscarMesa(Integer numeroMesa) {
		for (Iterator iterator = mesasFachade.getMesas().iterator(); iterator.hasNext();) {
			MesaBD m = (MesaBD) iterator.next();
			if(m.getPk().getNumero().equals(numeroMesa))
				return m;
		}
		return null;
	}

	public PlatoBD getPlato(Integer idPlato) {
		return this.mesasFachade.getPlato(idPlato);
	}

	public void generarComanda(ComandaBD c) {
		this.mesasFachade.generarComanda(c);
	}

	public void generarItemComanda(ItemComandaBD itemComandaBD) {
		this.mesasFachade.generarItemComanda(itemComandaBD);		
	}

	public List<PlatoBD>getPlatos() {
		return this.mesasFachade.getPlatos();
	}
	
	public void cerrarMesa(Integer restaurante, Integer mesa) {
		// TODO Auto-generated method stub
		MesaBD m = this.getMesaRestaurante(restaurante, mesa);
		m.setEstado("proxima a liberarse");
		mesasFachade.cerrarMesa(m);
	}

	public Float calcularTotalMesa(Integer restaurante, Integer mesa) {
		// TODO Auto-generated method stub
		MesaBD m = this.getMesaRestaurante(restaurante, mesa);
		return mesasFachade.calcularTotalMesa(m);
	}

}
